import 'package:flutter/material.dart';
import 'dart:math';

import 'package:flutter/services.dart';
import 'package:lottie/lottie.dart';

void main() {
  runApp(const MineSweeperApp());
}

class MineSweeperApp extends StatelessWidget {
  const MineSweeperApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Minesweeper',
      theme: ThemeData.dark(),
      home: const MineSweeperGame(),
    );
  }
}

class MineSweeperGame extends StatefulWidget {
  const MineSweeperGame({super.key});

  @override
  State<MineSweeperGame> createState() => _MineSweeperGameState();
}

class _MineSweeperGameState extends State<MineSweeperGame> {
  static const int rows = 10;
  static const int cols = 10;
  static const int mineCount = 15;
  late List<List<Cell>> grid;
  bool gameOver = false;
  bool gameWon = false;

  @override
  void initState() {
    super.initState();
    _initializeGame();
  }

  void _initializeGame() {
    grid = List.generate(rows, (r) => List.generate(cols, (c) => Cell()));
    _placeMines();
    _calculateNumbers();
    gameOver = false;
    gameWon = false;
  }

  void _placeMines() {
    Random random = Random();
    int placedMines = 0;
    while (placedMines < mineCount) {
      int r = random.nextInt(rows);
      int c = random.nextInt(cols);
      if (!grid[r][c].isMine) {
        grid[r][c].isMine = true;
        placedMines++;
      }
    }
  }

  void _calculateNumbers() {
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        if (grid[r][c].isMine) continue;
        int count = 0;
        for (int dr = -1; dr <= 1; dr++) {
          for (int dc = -1; dc <= 1; dc++) {
            int nr = r + dr, nc = c + dc;
            if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && grid[nr][nc].isMine) {
              count++;
            }
          }
        }
        grid[r][c].neighborMines = count;
      }
    }
  }

  void _handleTap(int r, int c) {
    if (gameOver || grid[r][c].isRevealed || grid[r][c].isFlagged) return;
    setState(() {
      if (grid[r][c].isMine) {
        gameOver = true;
        _revealAllMines();
      } else {
        _revealCell(r, c);
        _checkWin();
      }
    });
  }

  void _revealCell(int r, int c) {
    if (r < 0 || r >= rows || c < 0 || c >= cols || grid[r][c].isRevealed) return;
    grid[r][c].isRevealed = true;
    if (grid[r][c].neighborMines == 0) {
      for (int dr = -1; dr <= 1; dr++) {
        for (int dc = -1; dc <= 1; dc++) {
          _revealCell(r + dr, c + dc);
        }
      }
    }
  }

  void _revealAllMines() {
    for (var row in grid) {
      for (var cell in row) {
        if (cell.isMine) cell.isRevealed = true;
      }
    }
  }

  void _checkWin() {
    bool allNonMinesRevealed = true;
    for (var row in grid) {
      for (var cell in row) {
        if (!cell.isMine && !cell.isRevealed) {
          allNonMinesRevealed = false;
          break;
        }
      }
      if (!allNonMinesRevealed) break;
    }
    if (allNonMinesRevealed) {
      gameWon = true;
      _revealAllMines();
    }
  }

  void _handleLongPress(int r, int c) {
    if (gameOver || grid[r][c].isRevealed) return;
    HapticFeedback.lightImpact();
    setState(() {
      grid[r][c].isFlagged = !grid[r][c].isFlagged;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Minesweeper')),
      body: Stack(
        children: [
          Column(
            children: [
              Expanded(
                child: GridView.builder(
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: cols),
                  itemCount: rows * cols,
                  itemBuilder: (context, index) {
                    int r = index ~/ cols;
                    int c = index % cols;
                    return GestureDetector(
                      onTap: () => _handleTap(r, c),
                      onLongPress: () => _handleLongPress(r, c),
                      child: _buildCell(grid[r][c]),
                    );
                  },
                ),
              ),
              ElevatedButton(
                onPressed: () => setState(_initializeGame),
                child: const Text('Restart'),
              )
            ],
          ),
          if (gameWon)
            Container(
              color: Colors.black54,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Lottie.asset(
                      'assets/success.json',
                      width: 200,
                      height: 200,
                    ),
                    const SizedBox(height: 20),
                    const Text(
                      '恭喜你赢了！',
                      style: TextStyle(
                        fontSize: 24,
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: () => setState(_initializeGame),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.green,
                        padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
                      ),
                      child: const Text(
                        '重新开始',
                        style: TextStyle(fontSize: 18),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          if (gameOver)
            Container(
              color: Colors.black54,
              child: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Lottie.asset(
                      'assets/fail.json',
                      width: 200,
                      height: 200,
                    ),
                    const SizedBox(height: 20),
                    const Text(
                      '游戏结束！',
                      style: TextStyle(
                        fontSize: 24,
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: () => setState(_initializeGame),
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.red,
                        padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15),
                      ),
                      child: const Text(
                        '重新开始',
                        style: TextStyle(fontSize: 18),
                      ),
                    ),
                  ],
                ),
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildCell(Cell cell) {
    return Container(
      margin: const EdgeInsets.all(1),
      decoration: BoxDecoration(
        color: cell.isRevealed ? Colors.grey[400] : Colors.blue,
        border: Border.all(color: Colors.black),
      ),
      child: Center(
        child: cell.isRevealed
            ? (cell.isMine
            ? const Icon(Icons.dangerous, color: Colors.red)
            : Text(cell.neighborMines > 0 ? '${cell.neighborMines}' : '',
            style: const TextStyle(fontSize: 20)))
            : cell.isFlagged
            ? const Icon(Icons.flag, color: Colors.red)
            : null,
      ),
    );
  }
}

class Cell {
  bool isMine = false;
  bool isRevealed = false;
  bool isFlagged = false;
  int neighborMines = 0;
}
